<template>
  <div class="fission-report">
    <!-- 统计指标区域 -->
    <el-row :gutter="20">
      <el-col :span="6">
        <el-card class="fission-stat-card">
          <div class="fission-stat">
            <div class="stat-title">总裂变用户
              <el-tooltip placement="top">
                <div slot="content" style="max-width: 420px; line-height: 1.5;">
                  <div><strong>定义：</strong>去重的被邀请用户数</div>
                  <div><strong>去重字段：</strong>优先 <code>i.invitee_union_id</code>，为空时退化为 <code>i.invitee_openid</code></div>
                  <div><strong>关联：</strong><code>consul_nfc_fission_invite</code>（i）LEFT JOIN <code>consul_nfc_fission</code>（f） ON i.fission_id = f.id；仅统计 <code>f.status=有效</code></div>
                  <div><strong>筛选：</strong>受时间范围 / 商户 / 活动筛选限制</div>
                  <div><strong>注意：</strong>同一用户被多次邀请仅计1；不包含发起者本人</div>
                </div>
                <i class="el-icon-question"></i>
              </el-tooltip>
            </div>
            <div class="stat-value">{{ (fissionData.overview && fissionData.overview.total_fission_users) || 0 }}</div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card class="fission-stat-card">
          <div class="fission-stat">
            <div class="stat-title">发放奖励次数
              <el-tooltip placement="top">
                <div slot="content" style="max-width: 420px; line-height: 1.5;">
                  <div><strong>定义：</strong>统计已触发奖励的邀请记录数量</div>
                  <div><strong>判定条件：</strong><code>i.reward_status=已奖励</code> 或 <code>i.points_awarded&gt;0</code> 或 <code>i.coupon_id&gt;0</code></div>
                  <div><strong>关联：</strong><code>consul_nfc_fission_invite</code>（i）LEFT JOIN <code>consul_nfc_fission</code>（f） ON i.fission_id = f.id；仅统计 <code>f.status=有效</code></div>
                  <div><strong>筛选：</strong>受时间范围 / 商户 / 活动筛选限制</div>
                </div>
                <i class="el-icon-question"></i>
              </el-tooltip>
            </div>
            <div class="stat-value">{{ (fissionData.overview && fissionData.overview.total_rewards) || 0 }}</div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card class="fission-stat-card">
          <div class="fission-stat">
            <div class="stat-title">领取率
              <el-tooltip placement="top">
                <div slot="content" style="max-width: 420px; line-height: 1.5;">
                  <div><strong>定义：</strong>裂变分享页被领取的占比</div>
                  <div><strong>计算：</strong><code>claimed_views ÷ total_views × 100%</code></div>
                  <div><strong>来源表：</strong><code>consul_nfc_fission_views</code>（<code>is_claimed=1</code> 计入领取）</div>
                  <div><strong>筛选：</strong>受时间范围 / 商户 / 活动筛选限制</div>
                  <div><strong>注意：</strong>当 total_views=0 时，领取率记为 0%</div>
                </div>
                <i class="el-icon-question"></i>
              </el-tooltip>
            </div>
            <div class="stat-value">{{ (fissionData.overview && fissionData.overview.view_claim_rate) || 0 }}%</div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card class="fission-stat-card">
          <div class="fission-stat">
            <div class="stat-title">裂变浏览/领取
              <el-tooltip placement="top">
                <div slot="content" style="max-width: 420px; line-height: 1.5;">
                  <div><strong>定义：</strong>在当前筛选条件下，裂变分享页的总访问与领取情况</div>
                  <div><strong>计算：</strong><code>total_views / claimed_views</code></div>
                  <div><strong>来源表：</strong><code>consul_nfc_fission_views</code>（访问计总数，<code>is_claimed=1</code> 计入领取）</div>
                  <div><strong>筛选：</strong>受时间范围 / 商户 / 活动筛选限制</div>
                </div>
                <i class="el-icon-question"></i>
              </el-tooltip>
            </div>
            <div class="stat-value">{{ (fissionData.overview && fissionData.overview.total_views) || 0 }}/{{ (fissionData.overview && fissionData.overview.claimed_views) || 0 }}</div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 图表区域 -->
    <el-row :gutter="20" class="chart-row">
      <el-col :span="12">
        <el-card>
          <div slot="header">裂变层级分布
            <el-tooltip placement="top">
              <div slot="content" style="max-width: 440px; line-height: 1.5;">
                <div><strong>口径（占位）：</strong>按每条裂变（nfc_fission 记录）的"邀请条数"分桶：1-2→"1级"、3-5→"2级"、6+→"3级+"。这是"邀请强度分组"，不是传播链路层级</div>
                <div><strong>补充：</strong>当前按邀请表分组，不含"0邀请"的裂变；若需展示"0次邀请"，可增加补零逻辑单列显示</div>
                <div><strong>关联：</strong><code>consul_nfc_fission_invite</code>（i）LEFT JOIN <code>consul_nfc_fission</code>（f） ON i.fission_id = f.id；仅统计 <code>f.status=有效</code></div>
                <div><strong>筛选：</strong>受时间范围 / 商户 / 活动筛选限制</div>
                <div><strong>开发提示：</strong>该分布非"真实传播层级"。若需精确层级，请在数据层补充 parent 关系，并基于 referral 链路按 BFS/DFS 计算 level</div>
              </div>
              <i class="el-icon-question" style="margin-left:6px;color:#909399;"></i>
            </el-tooltip>
          </div>
          <div id="fissionLevelChart" style="height: 350px;"></div>
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card>
          <div slot="header">裂变时间分布
            <el-tooltip placement="top">
              <div slot="content" style="max-width: 420px; line-height: 1.5;">
                <div><strong>口径：</strong>按天统计 <code>i.create_time</code>（consul_nfc_fission_invite）产生的邀请数量</div>
                <div><strong>关联：</strong><code>consul_nfc_fission_invite</code>（i）LEFT JOIN <code>consul_nfc_fission</code>（f） ON i.fission_id = f.id；仅统计 <code>f.status=有效</code></div>
                <div><strong>筛选：</strong>受时间范围 / 商户 / 活动筛选限制</div>
                <div><strong>用途：</strong>观察裂变在日期维度的活跃度变化，评估活动节奏与投放时段</div>
                <div><strong>注意：</strong>按日聚合；若需按小时监控，请查看"实时统计"</div>
              </div>
              <i class="el-icon-question" style="margin-left:6px;color:#909399;"></i>
            </el-tooltip>
          </div>
          <div id="fissionTimeChart" style="height: 350px;"></div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import { nfcReportsAPI } from '@/api/nfc'
import * as echarts from 'echarts'

export default {
  name: 'FissionReport',
  props: {
    filters: { type: Object, required: true }
  },
  data() {
    return {
      loading: false,
      fissionData: {},
      chartInstances: {},
      chartResizeObservers: {}
    }
  },
  watch: {
    filters: { handler() { this.loadData() }, deep: true }
  },
  mounted() {
    this.loadData()
  },
  beforeDestroy() {
    // 清理图表实例
    Object.values(this.chartInstances).forEach(chart => chart && chart.dispose())
    // 清理尺寸监听器
    Object.values(this.chartResizeObservers).forEach(observer => {
      try {
        observer.disconnect()
      } catch (e) {
        console.warn('断开图表尺寸监听器失败:', e)
      }
    })
  },
  methods: {
    async loadData() {
      try {
        this.loading = true
        const response = await nfcReportsAPI.getFissionReport(this.filters)
        this.fissionData = response.data || {}
        this.$nextTick(() => this.renderFissionCharts(this.fissionData))
      } catch (error) {
        console.error('加载裂变数据失败：', error)
        this.$message.error('加载数据失败')
      } finally {
        this.loading = false
      }
    },
    // 渲染裂变图表
    renderFissionCharts(data) {
      // 裂变层级分布（柱状图）
      this.renderChart('fissionLevelChart', {
        title: { text: '' },
        tooltip: {
          trigger: 'axis',
          axisPointer: { type: 'shadow' }
        },
        xAxis: { 
          type: 'category', 
          data: data.level_labels || ['1级', '2级', '3级+'],
          axisLabel: { interval: 0 }
        },
        yAxis: { 
          type: 'value',
          name: '用户数量'
        },
        series: [{
          name: '裂变用户',
          data: data.level_counts || [],
          type: 'bar',
          itemStyle: { color: '#67C23A' },
          barWidth: '60%'
        }]
      })
      
      // 裂变时间分布（折线图）
      this.renderChart('fissionTimeChart', {
        title: { text: '' },
        tooltip: {
          trigger: 'axis',
          axisPointer: { type: 'cross' }
        },
        xAxis: { 
          type: 'category', 
          data: data.time_labels || [],
          axisLabel: { rotate: 45 }
        },
        yAxis: { 
          type: 'value',
          name: '邀请数量'
        },
        series: [{
          name: '每日邀请',
          data: data.time_counts || [],
          type: 'line',
          smooth: true,
          itemStyle: { color: '#E6A23C' },
          areaStyle: {
            color: {
              type: 'linear',
              x: 0, y: 0, x2: 0, y2: 1,
              colorStops: [
                { offset: 0, color: 'rgba(230, 162, 60, 0.3)' },
                { offset: 1, color: 'rgba(230, 162, 60, 0.1)' }
              ]
            }
          }
        }]
      })
    },
    
    // 通用图表渲染方法
    renderChart(containerId, option) {
      const container = document.getElementById(containerId)
      if (!container) return
      
      // 清理旧实例与观察器
      if (this.chartInstances[containerId]) {
        this.chartInstances[containerId].dispose()
        this.chartInstances[containerId] = null
      }
      if (this.chartResizeObservers[containerId]) {
        try {
          this.chartResizeObservers[containerId].disconnect()
        } catch (e) {
          console.warn('断开图表尺寸监听器失败:', e)
        }
        delete this.chartResizeObservers[containerId]
      }
      
      // 初始化图表
      const chart = echarts.init(container)
      chart.setOption(option)
      this.chartInstances[containerId] = chart
      
      // 添加 ResizeObserver 监听容器尺寸变化
      if (window.ResizeObserver) {
        const observer = new ResizeObserver(() => {
          try {
            chart.resize()
          } catch (e) {
            console.warn('图表自适应失败:', e)
          }
        })
        observer.observe(container)
        this.chartResizeObservers[containerId] = observer
      }
      
      // 防抖处理窗口 resize 事件
      const handleResize = () => {
        clearTimeout(this.resizeTimer)
        this.resizeTimer = setTimeout(() => {
          try {
            chart.resize()
          } catch (e) {
            console.warn('窗口 resize 图表适配失败:', e)
          }
        }, 100)
      }
      window.addEventListener('resize', handleResize)
    }
  }
}
</script>

<style scoped>
.fission-report {
  padding: 0;
}

/* 统计卡片样式 */
.fission-stat-card {
  border: 1px solid #EBEEF5;
  border-radius: 4px;
  height: 120px;
  margin-bottom: 20px;
}

.fission-stat-card .el-card__body {
  padding: 0;
  height: 100%;
}

.fission-stat {
  text-align: center;
  padding: 20px;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.stat-title {
  font-size: 14px;
  color: #606266;
  margin-bottom: 10px;
  line-height: 1.5;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.stat-value {
  font-size: 28px;
  font-weight: bold;
  color: #409EFF;
  line-height: 1.2;
}

/* 图表区域样式 */
.chart-row {
  margin-top: 20px;
}

.chart-row .el-card {
  border: 1px solid #EBEEF5;
  border-radius: 4px;
}

.chart-row .el-card__header {
  background-color: #F5F7FA;
  border-bottom: 1px solid #EBEEF5;
  padding: 18px 20px;
  font-weight: 500;
  color: #303133;
  display: flex;
  align-items: center;
  gap: 6px;
}

.chart-row .el-card__body {
  padding: 20px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .fission-stat {
    padding: 15px 10px;
  }
  
  .stat-title {
    font-size: 12px;
  }
  
  .stat-value {
    font-size: 24px;
  }
  
  .chart-row .el-card__body {
    padding: 15px;
  }
}
</style>